/**
 * Copyright (C) 2018-2022
 * All rights reserved, Designed By www.yixiang.co
 * 注意：
 * 本软件为www.yixiang.co开发研制，未经购买不得使用
 * 购买后可获得全部源代码（禁止转卖、分享、上传到码云、github等开源平台）
 * 一经发现盗用、分享等行为，将追究法律责任，后果自负
 */
package co.yixiang.yshop.module.order.controller.app.order;

import cn.hutool.core.util.ObjectUtil;
import co.yixiang.yshop.framework.common.pojo.CommonResult;
import co.yixiang.yshop.framework.security.core.annotations.PreAuthenticated;
import co.yixiang.yshop.framework.security.core.util.SecurityFrameworkUtils;
import co.yixiang.yshop.module.express.dal.redis.express.ExpressRedisDAO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoApiBaseDTO;
import co.yixiang.yshop.module.express.kdniao.model.dto.KdniaoApiDTO;
import co.yixiang.yshop.module.express.kdniao.model.vo.KdniaoApiVO;
import co.yixiang.yshop.module.express.kdniao.util.KdniaoUtil;
import co.yixiang.yshop.module.member.controller.app.user.vo.AppUserOrderCountVo;
import co.yixiang.yshop.module.order.controller.app.order.param.*;
import co.yixiang.yshop.module.order.controller.app.order.vo.AppConfirmOrderVo;
import co.yixiang.yshop.module.order.controller.app.order.vo.AppStoreOrderQueryVo;
import co.yixiang.yshop.module.order.service.storeorder.AppStoreOrderService;
import co.yixiang.yshop.module.shop.controller.app.vo.WriteOffDTO;
import com.egzosn.pay.spring.boot.core.PayServiceManager;
import com.egzosn.pay.web.support.HttpRequestNoticeParams;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;

import static co.yixiang.yshop.framework.common.exception.util.ServiceExceptionUtil.exception;
import static co.yixiang.yshop.framework.common.pojo.CommonResult.success;
import static co.yixiang.yshop.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static co.yixiang.yshop.module.express.enums.ErrorCodeConstants.EXPRESS_CONFIG_NOT_EXISTS;

/**
 * <p>
 * 订单控制器
 * </p>
 *
 * @author hupeng
 * @since 2023-6-23
 */
@Slf4j
@RestController
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Tag(name = "用户 APP - 订单模块")
@RequestMapping("/order")
public class AppOrderController {

    private final AppStoreOrderService appStoreOrderService;
    private final PayServiceManager manager;

    @Resource
    private ExpressRedisDAO expressRedisDAO;

    @PreAuthenticated
    @PostMapping("/confirm")
    @Operation(summary = "订单确认")
    public CommonResult<AppConfirmOrderVo> confirm(@Validated @RequestBody AppConfirmOrderParam param) {
        Long uid = getLoginUserId();
        return success(appStoreOrderService.confirmOrder(uid, param));

    }

    /**
     * 计算订单金额
     */
    @PreAuthenticated
    @PostMapping("/computed/{key}")
    @Parameter(name = "key", description = "确认订单返回唯一的key", required = true)
    @Operation(summary = "计算订单金额")
    public CommonResult<Map<String, Object>> computedOrder(@Validated @RequestBody AppComputeOrderParam param,
                                                           @PathVariable String key) {
        Long uid = getLoginUserId();
        return success(appStoreOrderService.computedOrder(uid, key, param));
    }

    /**
     * 订单创建
     */
    @PreAuthenticated
    @PostMapping("/create/{key}")
    @Operation(summary = "订单创建")
    @Parameter(name = "key", description = "唯一的uni值或者订单号", required = true, example = "10")
    public CommonResult<Map<String, Object>> create(@Valid @RequestBody AppOrderParam param,
                                                    @PathVariable String key) {
        Long uid = getLoginUserId();
        return success(appStoreOrderService.createOrder(uid, key, param));
    }


    /**
     * 支付查单
     */
    @PreAuthenticated
    @PostMapping(value = "/pay/orderQuery")
    @Operation(summary = "订单支付查询")
    public CommonResult<Boolean> orderQuery(@Valid @RequestBody AppPayParam param) throws Exception {
        Long uid = param.getUid();
        if (uid==null){
            uid = getLoginUserId();
        }
        return success(appStoreOrderService.orderQuery(uid, param));
    }


    /**
     * 订单支付
     */
    @PreAuthenticated
    @PostMapping(value = "/pay")
    @Operation(summary = "订单支付")
    public CommonResult<Map<String, String>> pay(@Valid @RequestBody AppPayParam param) throws Exception {
        Long uid = param.getUid();
        if (uid==null){
            uid = getLoginUserId();
        }
        return success(appStoreOrderService.pay(uid, param));
    }

//    /**
//     * 微信支付回调
//     *
//     * @param request
//     * @param response
//     * @throws Exception
//     */
//    @RequestMapping("pay/wxPayNotify")
//    @Operation(summary = "微信支付回调")
//    @PermitAll
//    public void wxPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
////        appStoreOrderService.wxPayNotify(request,response);
//    }

    /**
     * egzon支付回调地址  支付宝使用egzon形式 回调处理在AlipayMessageHandler
     *
     * @param request   请求
     * @param detailsId 列表id 商户表id
     * @return 支付是否成功
     */
    @RequestMapping(value = "payBack{detailsId}.json")
    public String payBack(HttpServletRequest request, @PathVariable String detailsId) {
        //底层通过调用pay模块的handler接受回调信息
        return manager.payBack(detailsId, new HttpRequestNoticeParams(request));
    }


    /**
     * 订单列表
     */
    @PreAuthenticated
    @GetMapping("/list")
    @Operation(summary = "订单列表")
    @Parameters({
            @Parameter(name = "type", description = "商品状态,-1全部 默认为0未支付 1待发货 2待收货 3待评价 4已完成 5退款中 6已退款 7退款",
                    required = true, example = "1"),
            @Parameter(name = "page", description = "页码,默认为1",
                    required = true, example = "1"),
            @Parameter(name = "limit", description = "页大小,默认为10",
                    required = true, example = "10      ")
    })
    public CommonResult<List<AppStoreOrderQueryVo>> orderList(@RequestParam(value = "type", defaultValue = "0") int type,
                                                              @RequestParam(value = "page", defaultValue = "1") int page,
                                                              @RequestParam(value = "limit", defaultValue = "10") int limit) {
        Long uid = getLoginUserId();
        return success(appStoreOrderService.orderList(uid, type, page, limit));
    }


    /**
     * 订单详情
     */
    @PreAuthenticated
    @GetMapping("/detail/{key}")
    @Operation(summary = "订单详情")
    @Parameter(name = "key", description = "唯一的uni值或者订单号", required = true, example = "10")
    public CommonResult<AppStoreOrderQueryVo> detail(@PathVariable String key,
                                                     @RequestParam(name = "uid",required = false) Long uid) {
        if (uid == null) {
            uid = getLoginUserId();
        }
        return success(appStoreOrderService.orderDetail(key, uid));
    }


    /**
     * 订单收货
     */
    @PreAuthenticated
    @PostMapping("/take")
    @Operation(summary = "订单收货")
    public CommonResult<Boolean> orderTake(@Validated @RequestBody AppDoOrderParam param) {
        Long uid = getLoginUserId();
        appStoreOrderService.takeOrder(param.getUni(), uid,"user");
        return success(true);
    }

    /**
     * 订单是否可以评价
     */
    @PreAuthenticated
    @PostMapping("/canComment/{id}")
    @Operation(summary = "订单是否")
    public CommonResult<Boolean> canComment(@PathVariable Long id) {
        return success(appStoreOrderService.canComment(id));
    }

    /**
     * 订单评价
     */
    @PreAuthenticated
    @PostMapping("/comments")
    @Operation(summary = "订单评价")
    public CommonResult<Boolean> comments(@Valid @RequestBody List<AppProductReplyParam> param) {
        Long uid = getLoginUserId();
        if (!param.isEmpty()) {
            for (AppProductReplyParam productReplyParam : param) {
                appStoreOrderService.orderComment(uid, productReplyParam.getUnique(),
                        productReplyParam.getComment(),
                        productReplyParam.getPics(), productReplyParam.getProductScore(), productReplyParam.getServiceScore());
            }

        }
        return success(true);
    }


    /**
     * 订单删除
     */
    @PreAuthenticated
    @DeleteMapping("/del")
    @Operation(summary = "订单删除")
    public CommonResult<Boolean> orderDel(@Validated @RequestBody AppDoOrderParam param) {
        Long uid = getLoginUserId();
        appStoreOrderService.removeOrder(param.getUni(), uid);
        return success(true);
    }


    /**
     * 订单取消   未支付的订单回退积分,回退优惠券,回退库存
     */
    @PreAuthenticated
    @PostMapping("/cancel")
    @Operation(summary = "订单取消")
    public CommonResult<Boolean> cancelOrder(@Validated @RequestBody AppHandleOrderParam param) {
        Long uid = getLoginUserId();
        appStoreOrderService.cancelOrder(param.getId(), uid);
        return success(true);
    }

    /**
     * 订单退款   已支付未发货的订单退款,回退积分,回退优惠券,回退库存
     */
    @PreAuthenticated
    @PostMapping("/refund")
    @Operation(summary = "已支付未发货订单退款")
    public CommonResult<Boolean> refundOrder(@Validated @RequestBody AppHandleOrderParam param) {
        Long uid = getLoginUserId();
        appStoreOrderService.refundOrder(param.getId(), uid);
        return success(true);
    }

    /**
     * 个人中心订单统计
     */
    @PreAuthenticated
    @PostMapping("/user_count")
    @Operation(summary = "个人中心订单统计")
    public CommonResult<AppUserOrderCountVo> countOrder() {
        Long uid = getLoginUserId();
        return success(appStoreOrderService.orderStatistics(uid));
    }


    /**
     * 获取物流信息
     */
    @PreAuthenticated
    @PostMapping("/order/express")
    @Operation(summary = "获取物流信息")
    public CommonResult<KdniaoApiVO> express(@RequestBody AppExpressParam appExpressParam) {
        KdniaoApiBaseDTO kdniaoApiBaseDTO = expressRedisDAO.get();
        if (ObjectUtil.isEmpty(kdniaoApiBaseDTO)) throw exception(EXPRESS_CONFIG_NOT_EXISTS);
        KdniaoApiDTO params = new KdniaoApiDTO();
        params.setLogisticCode(appExpressParam.getLogisticCode());
        params.setShipperCode(appExpressParam.getShipperCode());
        params.setApiKey(kdniaoApiBaseDTO.getApiKey());
        params.setEBusinessID(kdniaoApiBaseDTO.getEBusinessID());
        //此处注意 这个地方分收费与免费当 目前用当免费免费当只支持圆通 申通 百世 如果是收费当 改里面RequestType参数 函数里有说明
        return success(KdniaoUtil.getLogisticInfo(params));

    }

    /**
     * 订单核销
     */
    @PreAuthenticated
    @PostMapping("writeOff")
    @Operation(summary = "订单核销")
    public CommonResult<Boolean> writeOff(@RequestBody WriteOffDTO dto) {
        appStoreOrderService.writeOff(SecurityFrameworkUtils.getLoginUser(), dto);
        return CommonResult.success(true);
    }

    /**
     * 修改订单地址
     */
    @PostMapping("/edit/address")
    @Operation(summary = "修改订单地址")
    public CommonResult<Boolean> editAddress(@Valid @RequestBody AppEditOrderAddressParam param) {
        Long uid = getLoginUserId();
        return success(appStoreOrderService.editAddress(uid, param));
    }

}

